<?php require_once("Log.class.php");

/**
 * The LogFile class extends the basic Log class and enables the developer
 * to store the messagestack in a flat file. All the messages will be stored
 * on a single line.
 *
 * @author Dennis de Greef
 * @version 1.0
 */
class LogFile extends Log 
{ 
    /**
     * The filename of the log file to be used in the object
     * @var string
     */
    private $fileName;
    /**
     * The resource of the opened log file
     * @var resource
     */
    private $logResource;
    
    /**
     * When the object is created, the constructor will check if the file
     * which was provided in the first argument is available. If not, it
     * will attempt to create the file by using touch(). Then it will
     * open the file and store the resource in the object so it can be
     * used.
     *
     * @version 1.0
     * @throws Exception If logfile could not be created with touch()
     * @throws Exception If logfile could not be accessed for reading/writing
     * @param string $fileName
     * @return object
     */
    public function __construct($fileName) 
    {
        $fileName = ''.$fileName;
        $this->fileName = $fileName;
        if(!file_exists($fileName)) 
        {
            if(!touch($fileName))
                Throw new Exception('Logfile "' . $fileName . '" could not be created');
        }
        if(!($this->logResource = fopen($fileName, 'a+')))
            Throw new Exception('Logfile ' . $fileName . ' could not be accessed for reading/writing');
    }
    
    /**
     * By resetting the file pointer to the beginning of the opened file and
     * then processing the whole file, we get an array with all the current
     * log messages. If the file is empty it will return an empty array.
     *
     * @version 1.0
     * @return array
     */
    public function read() 
    {
        rewind($this->logResource);
        
        $logMessages = array();
        $fileContents = '';
        
        while (!feof($this->logResource)) $fileContents .= fgets($this->logResource, 1024);
        
        if (strlen($fileContents) > 0) 
        {
            foreach(explode(PHP_EOL, rtrim($fileContents, PHP_EOL)) as $sLogEntry) 
            {
                $aLogEntry = explode(',', $sLogEntry, 5);
            
                $logMessages[] = array('timestamp' => $aLogEntry[0],
                                       'type'      => $aLogEntry[1],
                                       'ipaddress' => $aLogEntry[2],
                                       'filename'  => $aLogEntry[3],
                                       'message'   => $aLogEntry[4]);
            }
        }
        return $logMessages;
    }
    
    /**
     * Truncate the logfile to 0 bytes. After truncating it is still possible
     * to write new log entries to the file.
     * @return void
     */
    public function clear() 
    {
        ftruncate($this->logResource, 0);
    }
    
    /**
     * Entries are stored in the parent class. By using the commit function
     * we retrieve the message stack from the parent class and process it.
     * After all the messages are written to the file we clear the message
     * stack so we can use it again for new messages.
     *
     * @version 1.0
     * @return void
     */
    public function commit() 
    {
        foreach($this->getStack() as $aLogmessage) 
        {
            fwrite($this->logResource
                 , $aLogmessage['timestamp'] . ',' 
                 . $aLogmessage['type'] . ',' 
                 . $aLogmessage['ipaddress'] . ',' 
                 . $aLogmessage['filename'] . ',' 
                 . str_replace(array("\n", "\r"), ""
                 , $aLogmessage['message']) . PHP_EOL);    
        }
        $this->clearStack();
    }
    
    /**
     * Clear the message-stack after commiting and close the file pointer
     */
    public function __destruct() 
    {
        $this->commit();
        fclose($this->logResource);
    }
} 